"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const geoserver_js_1 = require("./util/geoserver.js");
const about_js_1 = __importDefault(require("./about.js"));
class LayerClient {
    constructor(url, auth) {
        this.url = url;
        this.auth = auth;
    }
    async get(workspace, layerName) {
        let qualifiedName;
        if (workspace) {
            qualifiedName = `${workspace}:${layerName}`;
        }
        else {
            qualifiedName = layerName;
        }
        const response = await fetch(this.url + 'layers/' + qualifiedName + '.json', {
            credentials: 'include',
            method: 'GET',
            headers: {
                Authorization: this.auth
            }
        });
        if (!response.ok) {
            const grc = new about_js_1.default(this.url, this.auth);
            if (await grc.exists()) {
                return;
            }
            else {
                const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
                throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
            }
        }
        return response.json();
    }
    async modifyAttribution(workspace, layerName, attributionText, attributionLink) {
        let qualifiedName;
        if (workspace) {
            qualifiedName = `${workspace}:${layerName}`;
        }
        else {
            qualifiedName = layerName;
        }
        const jsonBody = await this.get(workspace, layerName);
        if (!jsonBody || !jsonBody.layer || !jsonBody.layer.attribution) {
            throw new geoserver_js_1.GeoServerResponseError(`layer '${workspace}:${layerName}' misses the property 'attribution'`);
        }
        if (attributionText) {
            jsonBody.layer.attribution.title = attributionText;
        }
        if (attributionLink) {
            jsonBody.layer.attribution.href = attributionLink;
        }
        const url = this.url + 'layers/' + qualifiedName + '.json';
        const response = await fetch(url, {
            credentials: 'include',
            method: 'PUT',
            headers: {
                Authorization: this.auth,
                'content-type': 'application/json'
            },
            body: JSON.stringify(jsonBody)
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
    }
    async getAll() {
        const response = await fetch(this.url + 'layers.json', {
            credentials: 'include',
            method: 'GET',
            headers: {
                Authorization: this.auth
            }
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
        return response.json();
    }
    async getLayers(workspace) {
        const response = await fetch(this.url + 'workspaces/' + workspace + '/layers.json', {
            credentials: 'include',
            method: 'GET',
            headers: {
                Authorization: this.auth,
            }
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
        return await response.json();
    }
    async getWmsLayer(workspace, datastore, layerName) {
        const response = await fetch(this.url + 'workspaces/' + workspace + '/wmsstores/' + datastore + '/wmslayers/' + layerName + '.json', {
            credentials: 'include',
            method: 'GET',
            headers: {
                Authorization: this.auth,
            }
        });
        if (!response.ok) {
            const grc = new about_js_1.default(this.url, this.auth);
            if (await grc.exists()) {
                return;
            }
            else {
                const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
                throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
            }
        }
        return await response.json();
    }
    async getWmtsLayer(workspace, datastore, layerName) {
        const response = await fetch(this.url + 'workspaces/' + workspace + '/wmtsstores/' + datastore + '/layers/' + layerName + '.json', {
            credentials: 'include',
            method: 'GET',
            headers: {
                Authorization: this.auth,
            }
        });
        if (!response.ok) {
            const grc = new about_js_1.default(this.url, this.auth);
            if (await grc.exists()) {
                return;
            }
            else {
                const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
                throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
            }
        }
        return await response.json();
    }
    async publishFeatureTypeDefaultDataStore(workspace, nativeName, name, title, srs, enabled, abstract) {
        const body = {
            featureType: {
                name: name,
                nativeName: nativeName || name,
                title: title || name,
                srs: srs || 'EPSG:4326',
                enabled: enabled,
                abstract: abstract || ''
            }
        };
        const response = await fetch(this.url + 'workspaces/' + workspace + '/featuretypes', {
            credentials: 'include',
            method: 'POST',
            headers: {
                Authorization: this.auth,
                'content-type': 'application/json'
            },
            body: JSON.stringify(body)
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
    }
    async publishFeatureType(workspace, dataStore, nativeName, name, title, srs, enabled, abstract, nativeBoundingBox) {
        if (nativeBoundingBox && !nativeBoundingBox.crs) {
            nativeBoundingBox.crs = {
                '@class': 'projected',
                $: srs
            };
        }
        const body = {
            featureType: {
                name: name || nativeName,
                nativeName: nativeName,
                title: title || name,
                srs: srs || 'EPSG:4326',
                enabled: enabled,
                abstract: abstract || '',
                nativeBoundingBox: nativeBoundingBox
            }
        };
        const response = await fetch(this.url + 'workspaces/' + workspace + '/datastores/' + dataStore + '/featuretypes', {
            credentials: 'include',
            method: 'POST',
            headers: {
                Authorization: this.auth,
                'content-type': 'application/json'
            },
            body: JSON.stringify(body)
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
    }
    async getFeatureType(workspace, datastore, name) {
        const url = this.url + 'workspaces/' + workspace + '/datastores/' + datastore + '/featuretypes/' + name + '.json';
        const response = await fetch(url, {
            credentials: 'include',
            method: 'GET',
            headers: {
                Authorization: this.auth
            }
        });
        if (!response.ok) {
            const grc = new about_js_1.default(this.url, this.auth);
            if (await grc.exists()) {
                return;
            }
            else {
                const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
                throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
            }
        }
        return response.json();
    }
    async publishWmsLayer(workspace, dataStore, nativeName, name, title, srs, enabled, abstract) {
        const body = {
            wmsLayer: {
                name: name || nativeName,
                nativeName: nativeName,
                title: title || name || nativeName,
                srs: srs || 'EPSG:4326',
                enabled: enabled,
                abstract: abstract || ''
            }
        };
        const response = await fetch(this.url + 'workspaces/' + workspace + '/wmsstores/' + dataStore + '/wmslayers', {
            credentials: 'include',
            method: 'POST',
            headers: {
                Authorization: this.auth,
                'content-type': 'application/json'
            },
            body: JSON.stringify(body)
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
    }
    async publishDbRaster(workspace, coverageStore, nativeName, name, title, srs, enabled, abstract) {
        const body = {
            coverage: {
                name: name || nativeName,
                nativeName: nativeName,
                title: title || name,
                srs: srs,
                enabled: enabled,
                abstract: abstract || ''
            }
        };
        const response = await fetch(this.url + 'workspaces/' + workspace + '/coveragestores/' + coverageStore + '/coverages', {
            credentials: 'include',
            method: 'POST',
            headers: {
                Authorization: this.auth,
                'content-type': 'application/json'
            },
            body: JSON.stringify(body)
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
    }
    async deleteFeatureType(workspace, datastore, name, recurse) {
        const response = await fetch(this.url + 'workspaces/' + workspace + '/datastores/' + datastore + '/featuretypes/' + name + '?recurse=' + recurse, {
            credentials: 'include',
            method: 'DELETE',
            headers: {
                Authorization: this.auth
            }
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
    }
    async enableTimeCoverage(workspace, dataStore, name, presentation, resolution, defaultValue, nearestMatchEnabled, rawNearestMatchEnabled, acceptableInterval) {
        const body = {
            coverage: {
                metadata: {
                    entry: [
                        {
                            '@key': 'time',
                            dimensionInfo: {
                                enabled: true,
                                presentation: presentation || 'DISCRETE_INTERVAL',
                                resolution: resolution,
                                units: 'ISO8601',
                                defaultValue: {
                                    strategy: defaultValue
                                },
                                nearestMatchEnabled: nearestMatchEnabled,
                                rawNearestMatchEnabled: rawNearestMatchEnabled,
                                acceptableInterval: acceptableInterval
                            }
                        }
                    ]
                }
            }
        };
        const url = this.url + 'workspaces/' + workspace + '/coveragestores/' + dataStore + '/coverages/' + name + '.json';
        const response = await fetch(url, {
            credentials: 'include',
            method: 'PUT',
            headers: {
                Authorization: this.auth,
                'content-type': 'application/json'
            },
            body: JSON.stringify(body)
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
    }
    async enableTimeFeatureType(workspace, dataStore, name, attribute, presentation, resolution, defaultValue, nearestMatchEnabled, rawNearestMatchEnabled, acceptableInterval) {
        const body = {
            featureType: {
                metadata: {
                    entry: [
                        {
                            '@key': 'time',
                            dimensionInfo: {
                                attribute: attribute,
                                presentation: presentation,
                                resolution: resolution,
                                units: 'ISO8601',
                                defaultValue: {
                                    strategy: defaultValue
                                },
                                nearestMatchEnabled: nearestMatchEnabled,
                                rawNearestMatchEnabled: rawNearestMatchEnabled,
                                acceptableInterval: acceptableInterval
                            }
                        }
                    ]
                }
            }
        };
        const url = this.url + 'workspaces/' + workspace + '/datastores/' + dataStore + '/featuretypes/' + name + '.json';
        const response = await fetch(url, {
            credentials: 'include',
            method: 'PUT',
            headers: {
                Authorization: this.auth,
                'content-type': 'application/json'
            },
            body: JSON.stringify(body)
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
    }
    async getCoverage(workspace, coverageStore, name) {
        const url = this.url + 'workspaces/' + workspace + '/coveragestores/' + coverageStore + '/coverages/' + name + '.json';
        const response = await fetch(url, {
            credentials: 'include',
            method: 'GET',
            headers: {
                Authorization: this.auth
            }
        });
        if (!response.ok) {
            const grc = new about_js_1.default(this.url, this.auth);
            if (await grc.exists()) {
                return;
            }
            else {
                const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
                throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
            }
        }
        return response.json();
    }
    async renameCoverageBands(workspace, dataStore, layername, bandNames) {
        const body = {
            coverage: {
                dimensions: {
                    coverageDimension: []
                }
            }
        };
        bandNames.forEach(bandName => {
            body.coverage.dimensions.coverageDimension.push({
                name: bandName
            });
        });
        const url = this.url + 'workspaces/' + workspace + '/coveragestores/' + dataStore + '/coverages/' + layername + '.json';
        const response = await fetch(url, {
            credentials: 'include',
            method: 'PUT',
            headers: {
                Authorization: this.auth,
                'content-type': 'application/json'
            },
            body: JSON.stringify(body)
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
    }
}
exports.default = LayerClient;
